from fastapi import APIRouter, Request, Depends, Form, BackgroundTasks
from fastapi.responses import RedirectResponse, HTMLResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session
from sqlalchemy import or_, delete
from auth.db import SessionLocal
from devices.models import Device
from ecg.models import ECGRecord
from auth.models import Alert
from auth.utils import get_current_user_info
from logging_config import setup_logging
from cache import redis_cache
import re

logger = setup_logging()
router = APIRouter()
templates = Jinja2Templates(directory="templates")

# ========== 优化点1: 预编译正则表达式 ==========
DEVICE_ID_PATTERN = re.compile(r"^ECG\d{10}$")
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()


# ========== 优化点2: 异步缓存任务 ==========
def cache_device_async(device_id: str, name: str, username: str):
    """后台异步缓存设备，不阻塞主流程"""
    if redis_cache.is_available():
        try:
            redis_cache.set_device(device_id, {
                "device_id": device_id,
                "name": name,
                "owner": username,
                "online": False
            })
            logger.info(f"设备 {device_id} 已缓存")
        except Exception as e:
            logger.warning(f"设备缓存失败: {e}")


# 显示设备管理页面
@router.get("/devices", response_class=HTMLResponse)
def device_page(request: Request, page: int = 1, sn: str = "", db: Session = Depends(get_db)):
    username, role = get_current_user_info(request)
    # 未登录
    if not username:
        return RedirectResponse(url="/login", status_code=303)

    # 统一小写，没有则默认 user
    role = (role or "user").strip().lower()

    # 医生禁止访问
    if role == "doctor":
        return RedirectResponse(url="/?msg=permission_denied", status_code=303)
    logger.info(f"{username}查看设备")
    # 普通用户只能看到自己绑定的设备（不分页）
    if role == "user":
        devices = db.query(Device).filter(Device.owner == username).all()
        return templates.TemplateResponse("dashboard.html", {
            "request": request,
            "username": username,
            "role": role,
            "devices": devices,
            "active_tab": "devices"
        })

    # 管理员 / 超级管理员查看全部设备（分页 + 搜索）
    else:
        page = max(1, page)  # 确保页码至少为1
        page_size = 10

        # 构建查询（支持按 SN 搜索）
        query = db.query(Device)
        if sn:
            query = query.filter(Device.device_id.contains(sn))

        # 查询总数
        total_devices = query.count()
        total_pages = max(1, (total_devices + page_size - 1) // page_size)

        # 如果当前页超过总页数，重定向到最后一页
        if page > total_pages:
            page = total_pages

        # 查询当前页数据
        devices = query.offset((page - 1) * page_size).limit(page_size).all()

        return templates.TemplateResponse("dashboard.html", {
            "request": request,
            "username": username,
            "role": role,
            "devices": devices,
            "active_tab": "devices",
            "current_page": page,
            "total_pages": total_pages,
            "search_sn": sn  # 返回搜索关键词到模板
        })


# ========== 优化后的添加设备接口 ==========
@router.post("/devices/add")
def add_device(
        request: Request,
        background_tasks: BackgroundTasks,
        device_id: str = Form(...),
        name: str = Form(...),
        db: Session = Depends(get_db)
):
    username, role = get_current_user_info(request)

    # 1. 未登录
    if not username:
        return RedirectResponse(url="/login", status_code=303)

    # 2. 非普通用户禁止绑定（放最前面）
    if role != "user":
        return RedirectResponse(url="/devices?msg=permission_denied", status_code=303)

    # ========== 优化点3: 使用预编译的正则表达式 ==========
    # 3. 校验设备编号格式和长度（合并校验）
    if not DEVICE_ID_PATTERN.match(device_id) or len(device_id) != 13:
        return RedirectResponse(url="/devices?msg=invalid_format", status_code=303)

    # 4. 校验设备名称长度（合并校验）
    name_len = len(name)
    if name_len == 0:
        return RedirectResponse(url="/devices?msg=name_null", status_code=303)
    if name_len > 10:
        return RedirectResponse(url="/devices?msg=name_too_long", status_code=303)

    # ========== 优化点4: 使用exists()代替first()，仅检查存在性 ==========
    # 5. 检查设备编号是否存在（更快的exists查询）
    device_exists = db.query(Device.device_id).filter(Device.device_id == device_id).first() is not None
    if device_exists:
        return RedirectResponse(url="/devices?msg=device_exists", status_code=303)

    # 6. 检查设备名称是否存在
    name_exists = db.query(Device.name).filter(Device.name == name).first() is not None
    if name_exists:
        return RedirectResponse(url="/devices?msg=device_name_exists", status_code=303)

    # ========== 优化点5: 移除不必要的 refresh() ==========
    # 7. 创建设备并提交
    device = Device(device_id=device_id, name=name, owner=username)
    db.add(device)
    db.commit()
    # 不需要 db.refresh(device)，因为我们有所有需要的数据

    # ========== 优化点6: 后台异步缓存 ==========
    # 8. 使用BackgroundTasks异步缓存新设备，不阻塞响应
    background_tasks.add_task(cache_device_async, device_id, name, username)
    logger.info(f"{username}添加设备{device_id}")
    return RedirectResponse(url="/devices?msg=add_success", status_code=303)


# ========== 优化后的删除设备接口 ==========
@router.get("/devices/delete/{device_id}")
def delete_device(device_id: str, request: Request, db: Session = Depends(get_db)):
    username, role = get_current_user_info(request)

    # 获取设备
    device = db.query(Device).filter(Device.device_id == device_id).first()

    if role == "doctor":
        return RedirectResponse(url="/devices?msg=permission_denied", status_code=303)

    if not device:
        return RedirectResponse(url="/devices?msg=device_not_found", status_code=303)

    # 权限检查
    if role not in ["admin", "superadmin"] and device.owner != username:
        return RedirectResponse(url="/devices?msg=permission_denied", status_code=303)

    # ========== 优化点7: 使用批量删除SQL，而不是逐条删除 ==========
    # 批量删除报警记录（一条SQL完成）
    db.execute(delete(Alert).where(Alert.device_id == device_id))

    # 批量删除心电图数据（一条SQL完成）
    db.execute(delete(ECGRecord).where(ECGRecord.device_id == device_id))

    # 删除设备
    db.delete(device)
    db.commit()
    logger.info(f"{username}删除设备{device_id}")
    # 清除缓存
    redis_cache.delete_device(device_id)

    return RedirectResponse(url="/devices?msg=delete_success", status_code=303)